home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2005-06-15 | 28.7 KB | 1,070 lines
var old_note=null, cur_note=null, num_notes = 0; //to be set in init() and changed by add/delete var notes_folder = "~/Documents/VoiceNotes/"; var adding_note = false; function getNotes() { var list = widget.system("/bin/ls " + notes_folder, null).outputString; if (list !== undefined) { var notes = list.split("\n"); //this isn't going to scale well for a huge amount of notes - will need to rehtink this...... num_notes = notes.length-1; for (var i=0; i < num_notes; i++) { var notes_list = document.getElementById("notes"); var item = document.createElement("li"); item.innerText = notes[i].substring(0, notes[i].lastIndexOf(".")); item.setAttribute("note", notes_folder + notes[i]); notes_list.appendChild(item); } cur_note = 0; selectNote(0); } } function selectNote(note) { var notes = document.getElementById("notes"); cur_note = note; var all_notes = notes.getElementsByTagName("li"); if (old_note != null) { all_notes[old_note].style.background = "none"; all_notes[old_note].style.color = ""; } all_notes[cur_note].style.background = "#1E2E8B"; all_notes[cur_note].style.color = "#95BDEA"; old_note = cur_note; toggleButtons("play"); //incase they're playing another note... } function xButtonHandler() { if (atMenu) { deleteNote(); } else { if (!isPaused) pauseNote(); shuntScreens('right', 'play', function(){atMenu=true;}); } } function deleteNote() { if (num_notes > 0) { if (!adding_note) { //trash the file, rather than actually removing it: widget.system("/bin/mv " + getUnixFilePath(document.getElementById("notes").getElementsByTagName("li")[cur_note].getAttribute("note")) + " ~/.Trash/", null); } else { document.getElementById("edit_div").style.display = "none"; adding_note = false; } document.getElementById("notes").removeChild(document.getElementById("notes").getElementsByTagName("li")[cur_note]); old_note = null; num_notes--; if (cur_note != null) { if (cur_note >= num_notes) cur_note--; if (cur_note >= 4) { document.getElementById("notes").style.top = -14*(cur_note-4) + "px"; } if (cur_note >= 0) selectNote(cur_note); } setUpScrollBar(); toggleButtons("play"); //just incase ;) } } function addNote() { if (!adding_note) { //event.preventDefault(); //event.stopPropagation(); adding_note = true; var notes = document.getElementById("notes"); notes.style.top = 0; cur_note = 0; var item = document.createElement("li"); item.innerHTML = " "; //just sets the height, is all... shap u! if (notes.getElementsByTagName("li").length > 0) notes.insertBefore(item, notes.getElementsByTagName("li")[cur_note]); else notes.appendChild(item); if (old_note != null) old_note++; num_notes++; cur_note = 0; selectNote(cur_note); setUpScrollBar(); var edit_div = document.getElementById("edit_div"); edit_div.innerText = "New Note"; edit_div.style.display = "block"; /* the following is just putting the caret at the end of edit div so that the text can be edited :) Found this stuff in the KHTML source... */ setTimeout( function () { var range = document.createRange(); range.selectNodeContents(edit_div); var sel=window.getSelection(); sel.setBaseAndExtent(edit_div.firstChild, 0, edit_div.lastChild, edit_div.lastChild.length); //sel.collapseToEnd(); toggleButtons("record"); //setUpScrollBar(); }, 100); } } var recording_timer, show_time_elapsed=true; function recordNewNote() { if (VoiceNotes) { var note_name = document.getElementById("edit_div").innerText; document.getElementById("edit_div").style.display = "none"; document.getElementById("notes").getElementsByTagName("li")[cur_note].innerText = note_name; document.getElementById("notes").getElementsByTagName("li")[cur_note].setAttribute("note", notes_folder + note_name + ".m4a"); toggleButtons("stop"); document.getElementById("recording_title").innerText = "Recording"; document.getElementById("recording_name").innerText = note_name; document.getElementById("cur_rec_time").innerText = "00:00"; shuntScreens('left', 'record', function() { alert(notes_folder + note_name + ".m4a"); VoiceNotes.recordToFile(notes_folder + note_name + ".m4a"); var cur_rec_time = 0; recording_timer = setInterval( function () { cur_rec_time += 600; document.getElementById("cur_rec_time").innerText = formatTime(cur_rec_time); }, 1000); }); } } function stopIt() { if (VoiceNotes) { clearInterval(recording_timer); document.getElementById("recording_title").innerText = "Saving"; document.getElementById("async").style.display = "block"; anim.play('forward', null); setTimeout( //doing this so the async has a chance to spin... function() { VoiceNotes.stopRecording(); //needs to be threaded or sopething because it stops the async anim when run toggleButtons("play"); selectNote(0); anim.stop(); document.getElementById("async").style.display = "none"; shuntScreens('right', 'record', null); adding_note = false; }, 500); } } var end_time, isPaused = false, atMenu = true; function playNote() { document.getElementById("now_playing").innerText = document.getElementById("notes").getElementsByTagName("li")[cur_note].innerText; document.getElementById("cur_time").innerText = "00:00"; toggleButtons("pause"); document.getElementById("pause").src = "images/pause_normal.png"; //in case it's still on play shuntScreens('left', 'play', function() { //alert("file://" + encodeURI(document.getElementById("notes").getElementsByTagName("li")[cur_note].getAttribute("note"))); document.note_player.SetURL("file://" + encodeURI(document.getElementById("notes").getElementsByTagName("li")[cur_note].getAttribute("note"))); document.note_player.Play(); isPaused = false; alert('yo - now playing'); document.getElementById("outside_cur_time").style.display = "block"; end_time = document.note_player.GetEndTime(); atMenu = false; play(); }); } var play_interval; function play() { play_interval = setInterval( function() { var cur_time = document.note_player.GetTime(); if (cur_time < end_time) { document.getElementById("cur_time").innerText = formatTime(show_time_elapsed ? cur_time : (end_time - cur_time)); document.getElementById("progress_bar").style.width = ((cur_time/end_time)* 100) + "%"; } else { clearInterval(play_interval); toggleButtons("play"); document.getElementById("progress_bar").style.width = 0; document.getElementById("outside_cur_time").style.display = "none"; shuntScreens('right', 'play', null); atMenu = true; } }, 1000); } function pauseNote() { var pause_button = document.getElementById("pause"); if (!isPaused) { document.note_player.Stop(); clearInterval(play_interval); pause_button.src = "images/play_normal.png"; document.getElementById("outside_cur_time").style.display = "none"; //shuntScreens('right', 'play', null); } else { document.note_player.Play(); play(); pause_button.src = "images/pause_normal.png"; document.getElementById("outside_cur_time").style.display = "block"; if (atMenu) { shuntScreens('left', 'play', null); toggleButtons("pause"); } atMenu = false; } isPaused = !isPaused; } function switchTime() { show_time_elapsed=!show_time_elapsed var cur_time = document.note_player.GetTime(); if (show_time_elapsed) { document.getElementById("cur_time").innerText = formatTime(cur_time); document.getElementById("time_type").innerText = "Time Elapsed: "; } else { document.getElementById("cur_time").innerText = formatTime((end_time - cur_time)); document.getElementById("time_type").innerText = "Remaining Time: "; } } function setTime(e) { //get percentage across they clicked: var perc = ((e.clientX - e.target.offsetLeft) / e.target.offsetWidth); document.note_player.SetTime(end_time * perc); } function formatTime(time) { var units = Math.floor(time/(600)); //actually total seconds assuming a document.note_player.GetTimeScale() of 600 var minutes = Math.floor(units/(60)); var seconds = units%60; if (minutes < 10) minutes = "0" + minutes; if (seconds < 10) seconds = "0" + seconds; return minutes + ":" + seconds; } function shuntScreens(dir, which, callBack) { var el = document.getElementById("screens"); if (which == "play") { document.getElementById("recording_screen").style.display = "none"; document.getElementById("playing_screen").style.display = "inline-block"; } else { document.getElementById("recording_screen").style.display = "inline-block"; document.getElementById("playing_screen").style.display = "none"; } var to, from; if (dir == "left") { to = -130; from = 0; } else { to = 0; from = -130; } var dif = -Math.abs(to - from); var pi = Math.PI; var i = 0; var points = []; for (var theta=0; theta < 90; theta+=10) { var step; if (to > from) step = Math.cos((theta*pi)/180); else step = Math.sin((theta*pi)/180); points.push(dif*step); } var inter = setInterval( function() { if (++i < points.length) { el.style.left = points[i] + "px"; } else { el.style.left = to + "px"; clearInterval(inter); if (callBack != null) callBack(); } }, 10); } var isScrolling = false, scrollint = null; function scrollUp() { if (atMenu) { if (--cur_note >= 0) { selectNote(cur_note); if (cur_note >= 4) { document.getElementById("notes").style.top = -14*(cur_note-4) + "px"; } document.getElementById("up_arrow").style.visibility = (cur_note == 0) ? "hidden" : "visible"; document.getElementById("down_arrow").style.visibility = "visible"; setUpScrollBar(); } else { cur_note = 0; cancelScroll(); } } } function scrollDown() { if (atMenu) { if (++cur_note < num_notes) { selectNote(cur_note); if (cur_note > 4) { document.getElementById("notes").style.top = -14*(cur_note-4) + "px"; } document.getElementById("up_arrow").style.visibility = "visible"; document.getElementById("down_arrow").style.visibility = (cur_note == num_notes-1) ? "hidden" : "visible"; setUpScrollBar(); } else { cur_note = num_notes-1; cancelScroll(); } } } function cancelScroll() { isScrolling = false; clearInterval(scrollint); scrollint = null; } function handleScroll(direction) { if (atMenu) { isScrolling = true; var dir = direction; setTimeout( function() { if (isScrolling) { var scroller = (dir == "up") ? "scrollUp()" : "scrollDown()"; if (scrollint == null) scrollint = setInterval(scroller, 100); } }, 500); } } function setUpScrollBar() { var scrollbar = document.getElementById("scroll_bar"); var notes_cont = document.getElementById("notes_container"); var notes = document.getElementById("notes"); var scroll_tab = document.getElementById("scroll_tab"); var ratio = notes_cont.offsetHeight/notes.offsetHeight; if (ratio < 1) { scroll_tab.style.top = (-1*ratio) * notes.offsetTop + 1 + "px"; scroll_tab.style.height = ratio*scrollbar.offsetHeight + "px"; scroll_tab.style.display = "block"; } else { scroll_tab.style.display = "none"; } } //the following function traps the return key for adding a note, and function handleKeyPress(e) { //alert(e.charCode); if (!help_running) { //i'll find a better way of handling all this when I wake up :'( if (e.charCode == 13 && e.target.id == "edit_div") { //handle adding the note on return - maybe do an animation for the record button. recordNewNote(); e.preventDefault(); e.stopPropagation(); } //alert(e.keyCode); if (e.keyCode == 38) { scrollUp(); e.preventDefault(); e.stopPropagation(); } if (e.keyCode == 40) { scrollDown(); e.preventDefault(); e.stopPropagation(); } if (e.keyCode == 32 && !adding_note) { if (atMenu) playNote(); else pauseNote(); e.preventDefault(); e.stopPropagation(); } } else { if (e.charCode == 27) cancelHelp(); else return false; } } function getUnixFilePath(file) { if (file.indexOf("file://localhost") != -1) file = file.substring(new String("file://localhost").length, file.length); //encode it so it doesn't matter if it's normal spaces or %20s file = encodeURI(file); file = file.replace(/%20/g,"\\ "); file = decodeURI(file); return file; } function getFileName(file) { var tmp = file.split("/"); tmp = tmp[tmp.length-1]; tmp = tmp.replace(/\\ /g, " "); return tmp; } function folderExists(path) { var folders = path.split("/"); var folder = folders[folders.length-2]; parent_folder = path.substring(0, path.indexOf("/" + folder)); var list = widget.system("/bin/ls " + parent_folder, null).outputString; var regex = new RegExp("^" + folder + "$", "img"); if (regex.exec(list)) return true; return false; } function expandTilde(path) { //find a more full proof method for this if (path.charAt(0) == "~") { path = path.substring(1, path.length); var username = widget.system("/usr/bin/whoami", null).outputString.split("\n")[0]; //since we get a newline character too var full_path = "/Users/" + username + path; } else { return path; } return full_path; } function saveSettings() { toggleSettings(); } function toggleButtons(which) { var buts = document.getElementById("buttons").getElementsByTagName("img"); for (var i=0; i < buts.length; i++) { if (buts[i].className == "middle") { buts[i].style.display = (buts[i].id == which) ? "block" : "none"; } } } function toggleSettings() { var f = document.getElementById("front"); var p = document.getElementById("settings"); if (f.style.display != "none") { f.style.display = "none"; p.style.display = "block"; var bod = document.getElementsByTagName("body")[0]; bod.removeEventListener("mouseover", mouseOver, true); bod.removeEventListener("mouseout", mouseOut, true); //This should be done in init() but didn't seem to work...... //if they're registered, we get rid of the stuff on the back: if (VoiceNotes.isRegistered()) { //alert('registered'); document.getElementById("settings").style["background-image"] = "url(images/backside_registered.png)"; document.getElementById("register_button").style.display = "none"; document.getElementById("buy_button").style.display = "none"; } else { //alert('not registered yet'); } if (window.widget) widget.prepareForTransition("ToBack"); } else { p.style.display = "none"; f.style.display = "block"; var bod = document.getElementsByTagName("body")[0]; bod.addEventListener("mouseover", mouseOver, true); bod.addEventListener("mouseout", mouseOut, true); if (window.widget) widget.prepareForTransition("ToFront"); } if (window.widget) setTimeout("widget.performTransition()", 0); } function register() { if (VoiceNotes) VoiceNotes.registerWidget(); } function buy() { if (VoiceNotes) VoiceNotes.buyWidget(); } function done() { toggleSettings(); } function Animation(id, what, strip_width, loops, interval) { this.inter = null; this.instance = id; //i suppose this could possibly be done using random numbers instead, but... eval(this.instance + " = this"); //giving us a reference to the object - I don't like eval in general, but this is an easy way of getting round this problem this.element = document.getElementById(what); this.left = 0; this.cur_loop = 0; this.dx = 26; // no display so can't get offsetWidth this.element.offsetWidth + 10; this.strip_width = strip_width; this.loops = loops; this.interval = interval; this.isPlaying = false; this.end_point = 0; this.dir = "forward"; this.callBack = null; this.play = function(dir, callBack) { if (!this.isPlaying) { this.isPlaying = true; this.dir = dir; this.callBack = callBack; if (this.dir == "back") { this.end_point = this.strip_width * -1; this.left = 10; } else { this.end_point = 0; this.left = this.strip_width; } this.inter = setInterval(this.instance + ".roll()", this.interval); } } this.stop = function () { clearInterval(this.inter); this.isPlaying = false; } this.roll = function() { this.left -= this.dx; if (this.left >= this.end_point) { var pos = (this.dir == "back") ? this.left * -1 : this.left; this.element.style.backgroundPosition = pos + "px 0"; } else { if (this.loops > 0 && ++this.cur_loop >= this.loops) { clearInterval(this.inter); this.cur_loop = 0; this.isPlaying = false; if (this.callBack != null) { this.callBack(); this.callBack = null; } } else { this.element.style.backgroundPosition = "0 0"; this.left = (this.dir == "back") ? 10 : this.strip_width; } } } } //mouseover stuff for the 'i' button: var isShown = false, isAnimating = false; function mouseOver(e) { //e.cancelBubble = true; if (!isShown && !isAnimating) { //alert('yo'); //document.getElementById("flip").style.display = "block"; fade('flipper', 0, 1, function(){isAnimating=false;isShown = true;}); isAnimating = true; } if (e.target.parentNode.id == "flip" || e.target.id == "flip") { document.getElementById("flip_back").style.visibility = "visible"; } } function mouseOut(e) { //e.cancelBubble = true; if (e.target.id != "flipper" && e.target.parentNode.id != "flip") { document.getElementById("flip_back").style.visibility = "hidden"; } //had a lot fo trouble with event capturing, so going this route for now... //we'll see what happens with actual Tiger... if (e.clientY < 0 || e.clientX < 0 || e.clientY > 250 || e.clientX > 230) { if (!isAnimating) { fade('flipper', 1, 0, function(){isAnimating=false;isShown = false;}); isAnimating = true; } } } function infoMouseUp(e) { fade('flipper', 0, 0, function(){isAnimating=false;isShown = false;}); document.getElementById("flip_back").style.visibility = "hidden"; toggleSettings(); } function fade(el, from, to, callBack) { if (el == new String(el)) el = document.getElementById(el); //so we can pass a string for the id or an element var dif = Math.abs(to - from); var pi = Math.PI; var i = 0; //if (to < from && el.style.opacity > 0) return; var points = []; for (var theta=0; theta<90; theta+=10) { var step; if (to > from) step = Math.sin((theta*pi)/180); else step = Math.cos((theta*pi)/180); points.push(dif*step); } var inter = setInterval( function() { if (++i < points.length) { el.style.opacity = Math.max(0.01, points[i]); //fixing safari glitch } else { el.style.opacity = to; clearInterval(inter); if (callBack != null) callBack(); } }, 100); } //help stuff: var help_running = false; function getOffsetTop(element) { var top = 0; var el = element; do { top += el.offsetTop; el = el.parentNode; } while (el !== document.body); return top; } function getOffsetLeft(element) { var left = 0; var el = element; do { left += el.offsetLeft; el = el.parentNode; } while (el !== document.body); return left; } var help_canvas_pen, help_canvas_x_stretch, help_canvas_y_stretch; function showHelp() { //this is basically an animation showing how to use the widget: help_running = true; //HAHA - the following is almost a joke, isn't it? document.getElementById("cover").style.display = "block"; toggleSettings(); setTimeout( function() { showHelpText(0, function () { help_canvas_pen = 1; help_canvas_y_stretch = 4; help_canvas_x_stretch = 6; circleObject('screen', function () { setTimeout( function() { hideHelpText(0, function () { setTimeout( function() { showHelpText(1, function () { //help_canvas_pen = 3; help_canvas_y_stretch = 1.5; help_canvas_x_stretch = 4; circleObject('up', function () { setTimeout( function() { hideHelpText(1, function () { circleObject('down', function () { setTimeout( function() { help_canvas_y_stretch = 2; help_canvas_x_stretch = 2.5; circleObject('play', function () { showHelpText(2, function () { setTimeout( function() { hideHelpText(2, function () { showHelpText(3, function () { help_canvas_y_stretch = 1.5; help_canvas_x_stretch = 2; circleObject('delete', function() { setTimeout( function() { hideHelpText(3, function () { circleObject('new', function () { showHelpText(4, function () { setTimeout( function() { hideHelpText(4, function () { document.getElementById("new").src = "images/new_pressed.png"; setTimeout( function() { document.getElementById("new").src = "images/new_normal.png"; addNote(); help_canvas_y_stretch = 2.5; help_canvas_x_stretch = 6; circleObject('screen', function () { var edit_div = document.getElementById("edit_div"); var sel=window.getSelection(); sel.setBaseAndExtent(edit_div.firstChild, 0, edit_div.lastChild, edit_div.lastChild.length); sel.collapseToEnd(); showHelpText(5, function () { setTimeout( function() { hideHelpText(5, function () { deleteNote(); alert('yo'); document.getElementById("help_circle_canvas").style.display = "none"; setTimeout( function() { showHelpText(6, function () { setTimeout( function() { hideHelpText(6, function () { showHelpText(7, function () { setTimeout( function() { hideHelpText(7, function () { //document.getElementById("help_circle_canvas").style.display = "none"; document.getElementById("cover").style.display = "none"; toggleSettings(); }); //hideHelpText 7 }, 3500); }); //showHelpText 7 }); //hideHelpText 6 }, 3500); }, 100); //showHelpText 6 }, 1000); }); //hideHelpText 5 }, 3500); }); //showHelpText 5 }); //circleObject 'screen' }, 500); }); //hideHelpText 4 }, 1500); });//showHelpText 4 }); //circleObject 'new' });//hideHelpText 3 }, 3500); });//circleObject 'delete' });//showHelpText 3 });//hideHelpText 3 }, 3000); });//howHelpText 3 });//circleObject 'front' }, 1000); }); //fade 'help_circle_canvas' });//hideHelpText 1 }, 3500); });//circleObject 'nickname_combo' });//showHelpText 1 }, 1500); });//hideHelpText 0 }, 3500); });//circleObject 'screen' });//showHelpText 0 }, 1000); } function cancelHelp() { help_running = false; var help_text = document.getElementById("help_text"); document.getElementById("help_circle_canvas").style.display = "none"; document.getElementById("cover").style.display = "none"; var messages = help_text.getElementsByTagName("div"); for (var i=0; i < messages.length; i++) messages[i].style.opacity = 0; help_text.style.display = "none"; } function circleObject(obj, callBack) { if (!help_running) return false; if (obj == new String(obj)) obj = document.getElementById(obj); var help_context = help_canvas.getContext("2d"); help_canvas.style.display = "block"; help_canvas.style.top = (getOffsetTop(obj) - 15) + "px"; help_canvas.style.left = (getOffsetLeft(obj) - 15) + "px"; help_context.lineWidth = 1; //help_canvas_pen; help_context.lineJoin = "bevel"; help_context.lineCap = "round"; help_context.strokeStyle = "rgba(255, 0, 0, 0.8)"; help_context.clearRect(0, 0, 300, 300); help_context.save(); help_context.scale(help_canvas_x_stretch, help_canvas_y_stretch); help_context.beginPath(); help_context.moveTo(5, 10); var i=0; var inter = setInterval( function () { //alert(i); switch (i) { case 0: help_context.bezierCurveTo(5, 0, 20, 10, 20, 20); break; case 1: help_context.beginPath(); help_context.moveTo(20, 10); help_context.bezierCurveTo(30, 20, 20, 30, 15, 20); break; case 2: help_context.beginPath(); help_context.moveTo(20, 30); help_context.bezierCurveTo(10, 35, 5, 25, 5, 10); break; case 3: help_context.beginPath(); help_context.moveTo(5, 25); help_context.bezierCurveTo(2, 7, 9, 10, 0, 0); break; //Default: case 4: clearInterval(inter); help_context.restore(); if (callBack != null) callBack(); break; } help_context.stroke(); i++; }, 70); } function showHelpText(which, callBack) { if (!help_running) return false; var help_text = document.getElementById("help_text"); help_text.style.display = "block"; var messages = help_text.getElementsByTagName("div"); if (which > 0) messages[which-1].style.opacity = 0; fade(messages[which], 0, 0.9, function() { //setTimeout("help_text_shadow.paint()", 100); callBack(); }); } function hideHelpText(which, callBack) { if (!help_running) return false; var help_text = document.getElementById("help_text"); var messages = help_text.getElementsByTagName("div"); //if (which > 0) messages[which-1].style.opacity = 0; fade(messages[which], 0.9, 0, function () { help_text.style.display = "none"; callBack(); }); } var anim, help_canvas; function init() { anim = new Animation('saving_anim', 'async', 276, 0, 50); //set up the flip ('i') button: var bod = document.getElementsByTagName("body")[0]; bod.addEventListener("mouseover", mouseOver, true); bod.addEventListener("mouseout", mouseOut, true); document.getElementById("flip").addEventListener("mouseup", infoMouseUp, false); //and now set up our buttons: var buttons = document.getElementById("buttons").getElementsByTagName("img"); for (var i=0; i < buttons.length; i++) { buttons[i].addEventListener("mousedown", function(e) { e = e.target; var src = getFileName(e.src); src = src.split("_"); src = "images/" + src[0] + "_pressed.png"; e.src = src; }, true); buttons[i].addEventListener("mouseup", function(e) { e = e.target; var src = getFileName(e.src); src = src.split("_"); src = "images/" + src[0] + "_normal.png"; e.src = src; }, true); } if (window.widget) { //here we get all the files, then display them and select the first one (probably the last one to be used, actually) notes_folder = expandTilde(notes_folder); if (!folderExists(notes_folder)) { widget.system("/bin/mkdir " + notes_folder, null); } else { getNotes(); } toggleButtons("play"); setUpScrollBar(); } document.addEventListener("keydown", handleKeyPress, false); help_canvas = document.getElementById("help_circle_canvas"); } window.onload = init;